﻿import type { RequestOptions } from '@@/plugin-request/request';
import { RequestConfig, history } from '@umijs/max';
import { message, notification } from 'antd';
import { getToken, REFRESH_TOKEN, setToken } from './utils/storage';
import { RequestOptionsInit } from 'umi-request';
import { getLocale } from 'umi';
import { showReLoginModal } from './components/ReLoginModal';

// 错误处理方案： 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
  success: boolean;
  data: any;
  status?: number;
  msg?: string;
  showType?: ErrorShowType;
}

const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
  const { location = { pathname: '' } } = history;
  const authHeader = {
    // Authorization: ``,
    ContentType: 'application/json'
  };
  // if (location.pathname != LOGIN_PATH) {
  //   let token = getToken();
  //   if (token == null || token == '') {
  //     history.push(LOGIN_PATH);
  //   }
    // authHeader.Authorization = `${token}`;
  // }
  return {
    url: `${url}`,
    options: { ...options, interceptors: true, headers: { ...(options.headers), ...authHeader } },
  };
};

const responseInterceptor = (response: Response, { headers }: RequestOptionsInit) => {
  // 刷新token
  const token = response.headers?.get(REFRESH_TOKEN);

  if (token && token != null && token != '') {
    setToken(`bearer ${token}`);
  }
  return response
}
/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const requestConfig: RequestConfig = {
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res) => {
      const { success, data, status, msg, showType } =
        res as unknown as ResponseStructure;
      if (!success) {
        const error: any = new Error(msg);
        error.name = 'BizError';
        error.info = { status, msg, showType, data };
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { msg, status } = errorInfo;
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
              break;
            case ErrorShowType.WARN_MESSAGE:
              message.warning(msg);
              break;
            case ErrorShowType.ERROR_MESSAGE:
              message.error(msg);
              break;
            case ErrorShowType.NOTIFICATION:
              notification.open({
                description: msg,
                message: status,
              });
              break;
            case ErrorShowType.REDIRECT:
              // TODO: redirect
              break;
            default:
              message.error(msg);
          }
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(`Response status:${error.response.status}`);   
        if (error.response.status == 401) {
          // removeToken();
          showReLoginModal();
          return Promise.resolve();
        }     
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      // 拦截请求配置，进行个性化处理。
      const url = config?.url;
      const { location = { pathname: '' } } = history;
      const authHeader = {
        // Authorization: ``,
        Locale:``,
        ContentType: 'application/json'
      };
      // let token = getToken();
      // if (token == null || token == '') {
      //   history.push(LOGIN_PATH);
      // }
      // authHeader.Authorization = `${token}`;
      // { ...options,  
      authHeader.Locale = getLocale();
      return { ...config, interceptors: true, headers: { ...(config.headers), ...authHeader }, url };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      const token = response.headers[REFRESH_TOKEN]

      if (token && token != null && token != '') {
        setToken(`bearer ${token}`);
      }
      return response
    },
  ],
};
